package com.mjf.cjt.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mjf.cjt.domain.TOtherInStockOrder;
import com.mjf.cjt.domain.TOtherInStockOrderDetails;
import com.mjf.cjt.mapper.TOtherInStockOrderMapper;
import com.mjf.cjt.service.AsyncTMService;
import com.mjf.cjt.service.TOtherInStockOrderDetailsService;
import com.mjf.cjt.service.TOtherInStockOrderService;
import com.mjf.cjt.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class TOtherInStockOrderServiceImpl extends ServiceImpl<TOtherInStockOrderMapper, TOtherInStockOrder> implements TOtherInStockOrderService {
    @Autowired
    private TOtherInStockOrderDetailsService totherInStockOrderDetailsService;

    @Autowired
    private AsyncTMService asyncTMService;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void otherInStockOrder(String start, String end) {
        List<TOtherInStockOrder> list = list(Wrappers.<TOtherInStockOrder>lambdaQuery()
                .ge(StrUtil.isNotBlank( start), TOtherInStockOrder::getCreateTime, start)
                .le(StrUtil.isNotBlank( end), TOtherInStockOrder::getCreateTime, end)
                .eq(TOtherInStockOrder::getPushStatus, 0)
        );
        otherInStockOrder(list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void otherInStockOrderByIds(List<String> ids) {
        List<TOtherInStockOrder> list = list(Wrappers.<TOtherInStockOrder>lambdaQuery()
                .eq(TOtherInStockOrder::getPushStatus, 0)
                .in(TOtherInStockOrder::getId, ids));
        otherInStockOrder(list);
    }

    @Override
    public Page<TOtherInStockOrderListVo> queryOtherInStockOrder(TOtherInStockOrderQueryParam param) {

        Page<TOtherInStockOrderListVo> page = new Page<>(param.getPage(), param.getSize());
        page.setTotal(0);
        page.setRecords(new ArrayList<>());
        LambdaQueryWrapper<TOtherInStockOrder> qw = Wrappers.<TOtherInStockOrder>lambdaQuery()
                .ge(StrUtil.isNotBlank(param.getStart()), TOtherInStockOrder::getCreateTime, param.getStart())
                .le(StrUtil.isNotBlank(param.getEnd()), TOtherInStockOrder::getCreateTime, param.getEnd())
                .eq(TOtherInStockOrder::getPushStatus, param.getPushStatus())
                ;
        long count = count(qw);
        page.setTotal(count);
        qw.orderByDesc(TOtherInStockOrder::getCreateTime);
        qw.last("limit " + (param.getPage() - 1) * param.getSize() + "," + param.getSize());

        List<TOtherInStockOrder> list = list(qw);

        page.setRecords(list.stream().map(item -> TOtherInStockOrderListVo.builder()
            .id(item.getId())
            .externalCode(item.getExternalCode())
            .code(item.getCode())
            .voucherTypeCode(item.getVoucherTypeCode())
            .voucherDate(item.getVoucherDate())
            .businessTypeCode(item.getBusinessTypeCode())
            .rdStyleCode(item.getRdStyleCode())
            .warehouseCode(item.getWarehouseCode())
            .warehouseName(item.getWarehouseName())
            .departmentCode(item.getDepartmentCode())
            .departmentName(item.getDepartmentName())
            .partnerCode(item.getPartnerCode())
            .clerkCode(item.getClerkCode())
            .memo(item.getMemo())
            .dynamicPropertyKeys(item.getDynamicPropertyKeys())
            .dynamicPropertyValues(item.getDynamicPropertyValues())
            .build())
            .collect(Collectors.toList()));
        return page;
    }

    public void otherInStockOrder(List<TOtherInStockOrder> list) {

        if (CollectionUtil.isEmpty(list)) {
            return;
        }

        // 查询其他入库明细
        List<TOtherInStockOrderDetails> detailList =
                totherInStockOrderDetailsService.list(Wrappers.<TOtherInStockOrderDetails>lambdaQuery()
                        .in(TOtherInStockOrderDetails::getOrderId, list.stream()
                                .map(TOtherInStockOrder::getId).collect(Collectors.toList())));

        Map<Long, List<TOtherInStockOrderDetails>> detailMap =
                detailList.stream().collect(Collectors.groupingBy(TOtherInStockOrderDetails::getOrderId));

        List<TOtherInStockOrder> updates = new ArrayList<>();
        for (TOtherInStockOrder totherInStockOrder : list) {
            try {
                TOtherInStockOrderCreateVo.Dto vo = TOtherInStockOrderCreateVo.Dto.builder()
                        .ExternalCode(totherInStockOrder.getExternalCode())
                        .Code(totherInStockOrder.getExternalCode())
                        .VoucherType(TOtherInStockOrderCreateVo.Dto.VoucherType.builder()
                                .Code(totherInStockOrder.getVoucherTypeCode())
                                .VoucherDate(totherInStockOrder.getVoucherDate())
                                .build())
                        .BusinessType(TOtherInStockOrderCreateVo.Dto.BusinessType.builder()
                                .Code(totherInStockOrder.getBusinessTypeCode())
                                .build())
                        .RdStyle(TOtherInStockOrderCreateVo.Dto.RdStyle.builder()
                                .Code(totherInStockOrder.getRdStyleCode())
                                .build())
                        .Warehouse(TOtherInStockOrderCreateVo.Dto.Warehouse.builder()
                                .Code(totherInStockOrder.getWarehouseCode())
                                .Name(totherInStockOrder.getWarehouseName())
                                .build())
                        .Department(TOtherInStockOrderCreateVo.Dto.Department.builder()
                                .Code(totherInStockOrder.getDepartmentCode())
                                .Name(totherInStockOrder.getDepartmentName())
                                .build())
                        .Partner(TOtherInStockOrderCreateVo.Dto.Partner.builder()
                                .Code(totherInStockOrder.getPartnerCode())
                                .build())
                        .Clerk(TOtherInStockOrderCreateVo.Dto.Clerk.builder()
                                .Code(totherInStockOrder.getClerkCode())
                                .Memo(totherInStockOrder.getMemo())
                                .build())
                        .build();


                vo.setRDRecordDetails(detailMap.get(totherInStockOrder.getId()).stream().map(item ->
                        TOtherInStockOrderCreateVo.Dto.RDRecordDetails.builder()
                                .Code(item.getInventoryLocationRowNumber().toString())
                                .inventoryLocations(TOtherInStockOrderCreateVo.Dto.RDRecordDetails.inventoryLocations.builder()
                                        .Code(item.getInventoryCode())
                                        .build())
                                .Inventory(TOtherInStockOrderCreateVo.Dto.RDRecordDetails.Inventory.builder()
                                        .Code(item.getInventoryCode())
                                        .Name(item.getInventoryName())
                                        .build())
                                .Project(TOtherInStockOrderCreateVo.Dto.RDRecordDetails.Project.builder()
                                        .Code(item.getProjectCode())
                                        .Name(item.getProjectName())
                                        .build())
                                .Batch(item.getBatch())
                                .BaseQuantity(item.getBaseQuantity())
                                .Amount(item.getAmount())
                                .Price(item.getPrice())
                                .ProductionDate(item.getProductionDate().toString())
                                .ExpiryDate(item.getExpiryDate().toString())
                                .ExaminerDate(item.getExaminerDate().toString())
                                .build())
                        .collect(Collectors.toList())
                );

                TOtherInStockOrderCreateVo vo1 = TOtherInStockOrderCreateVo.builder()
                        .dto(vo)
                        .build();

                TFResultVO resultVO = asyncTMService.otherInStockOrder(vo1);
                totherInStockOrder.setPushId(resultVO.getData().getId());
                totherInStockOrder.setPushCode(resultVO.getData().getCode());
                totherInStockOrder.setPushStatus(1);
                totherInStockOrder.setPushResult(resultVO.getResult());
                totherInStockOrder.setPushTime(LocalDateTime.now());
                updates.add(totherInStockOrder);
            } catch (Exception e) {
                log.error("推送T+产成品入库单异常 {}, {}", e, totherInStockOrder);
            }
        }
        if (CollectionUtil.isNotEmpty(updates)) {
            updateBatchById(updates);
        }
    }
}
